package code;

import java.util.List;

import org.apache.log4j.Logger;

import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.MessageLite;

import common.Message;
import common.NetChannel;
import common.ServerAttributeKey;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.util.Attribute;
import utils.ByteUtils;

/**
 * 二进制转成mymessage
 * @author King
 *
 */
public class PBBytesToMessageDecode extends ByteToMessageDecoder
{
	private static final Logger log =Logger.getLogger(PBBytesToMessageDecode.class);
	
	private IMessageManager<GeneratedMessage, MessageLite> messageManager;
	
	
	public void setMessageManager(IMessageManager<GeneratedMessage, MessageLite> messageManager)
	{
		this.messageManager = messageManager;
	}
	
	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf msg,
			List<Object> out) throws Exception 
	{
		try {
			if(!msg.isReadable())
				return;
			Channel channel = ctx.channel();
			final Message myMsg = Message.newMessage();
			int lenth =ByteUtils.readVariaInt(msg);
			int avalable = msg.readableBytes();
			myMsg.setmId(ByteUtils.readVariaInt(msg));
			myMsg.sethId(ByteUtils.readVariaInt(msg));
			myMsg.setResponseId(ByteUtils.readVariaInt(msg));
			int bodyLenth = lenth-avalable+msg.readableBytes();
			//错误了直接把channel关闭
			if (lenth >=Message.MAX_MESSAGE_SIZE) {
				log.error("解析字节码太长，长度:"+lenth+"modelId"+myMsg.getmId()+"action"+myMsg.gethId()+"ip:"+channel.remoteAddress());
				channel.close();
			}
			Attribute<NetChannel> attr = channel.attr(ServerAttributeKey.netChannel);
			if(attr!=null)
			{
				myMsg.setChannel(attr.get());
			}
			
			if(bodyLenth!=0)
			{
				byte[] bytes= new byte[bodyLenth];
				msg.readBytes(bytes);
				MessageLite lite = messageManager.getMessage(myMsg.getmId(), myMsg.gethId());
				if(lite!=null)
				{
					MessageLite.Builder builder = lite.newBuilderForType();
					builder = builder.mergeFrom(bytes);
					myMsg.setBody(builder.build());
					builder=null;
					lite=null;
				}else
					log.error("没有获得对应的消息体moduleId:"+myMsg.getmId()+"actionId:"+myMsg.gethId()+"ip:"+channel.remoteAddress());
				bytes= null;
			}
			msg=null;
			out.add(myMsg);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("decode error"+"ip:"+ctx.channel().remoteAddress(), e);
			ctx.channel().close();
		}
	}
}
